package com.imxplus.example01

import akka.actor.{Actor, Props}
import akka.event.Logging
import akka.pattern._
import akka.util.Timeout
import com.imxplus.example01.Messages._

import scala.concurrent.duration._

object Actors {

  class BossActor extends Actor {
    val log = Logging(context.system, this)
    implicit val askTimeout = Timeout(5 seconds)

    import context.dispatcher

    var taskCount = 0

    override def receive: Receive = {
      case b: Business => {
        log.info("I must to do something, go, go, go!")
        println(self.path.address)

        val managerActors = (1 to 3) map {
          i => context.actorOf(Props[ManagerActor], s"manager-$i")
        }
        log.info("Start to ask managers ...")

        managerActors foreach {
          _ ? Meeting("Meeting to discuss big plans") map {
            case c: Confirm => {
              log.info("Got answer from {}", c.actorPath)

              log.info(c.actorPath.toString)
              log.info(c.actorPath.parent.toString)

              val manager = context.actorSelection(c.actorPath)
              manager ! DoAction("Do thing")
            }
          }
        }

      }

      case d: Done => {
        taskCount += 1
        if (taskCount == 3) {
          log.info("The project is done, we will earn much money.")
          context.system.terminate()
        }
      }
    }
  }

  class ManagerActor extends Actor {
    val log = Logging(context.system, this)

    override def receive: Receive = {
      case m: Meeting => {
        log.info("Receive meeting")
        Thread.sleep(6000L)
        log.info("Start to answer")
        sender() ! Confirm(s"I have receive command: ${m.content}", self.path)
      }
      case d: DoAction => {
        val workerActor = context.actorOf(Props[WorkerActor], "worker")
        workerActor forward d
      }
    }
  }

  class WorkerActor extends Actor {
    val log = Logging(context.system, this)

    override def receive: Receive = {
      case d: DoAction => {
        log.info("I have received task: {}", d)
        sender() ! Done("I have done work.")
      }
    }
  }

}
